

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=dark>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/my-blog/img/fluid.png">
  <link rel="icon" href="/my-blog/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="木舟">
  <meta name="keywords" content="python Vue Test 测试开发 自动化测试">
  
    <meta name="description" content="前言在学习完前端相关知识(html&#x2F;css&#x2F;js&#x2F;vue)后, 离我们向高级测试开发前进的道路中最后一个坎就只剩下 后端相关知识. 而后端相关知识中, 我们将会学习 django, 是属于 python 领域的框架. python也是我们相对熟悉的语言了, 所以学习起来, 会更加轻松一些. 什么是web后端web后端, 简单的理解: 提供&#x2F;存储&#x2F;修改数据的地方. web后端, 实际上就是一个web">
<meta property="og:type" content="article">
<meta property="og:title" content="django起步">
<meta property="og:url" content="https://walker_kwu.gitee.io/my-blog/2022/12/11/notes/django/strat/">
<meta property="og:site_name" content="My Blog">
<meta property="og:description" content="前言在学习完前端相关知识(html&#x2F;css&#x2F;js&#x2F;vue)后, 离我们向高级测试开发前进的道路中最后一个坎就只剩下 后端相关知识. 而后端相关知识中, 我们将会学习 django, 是属于 python 领域的框架. python也是我们相对熟悉的语言了, 所以学习起来, 会更加轻松一些. 什么是web后端web后端, 简单的理解: 提供&#x2F;存储&#x2F;修改数据的地方. web后端, 实际上就是一个web">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://www.yuan316.com/post/Django3.2%E6%A1%86%E6%9E%B6/assets/image-20210723182232002.png">
<meta property="og:image" content="http://www.yuan316.com/post/Django3.2%E6%A1%86%E6%9E%B6/assets/image-20210723181947547.png">
<meta property="article:published_time" content="2022-12-11T05:02:27.000Z">
<meta property="article:modified_time" content="2023-05-23T10:37:53.250Z">
<meta property="article:author" content="木舟">
<meta property="article:tag" content="测试开发">
<meta property="article:tag" content="测试平台">
<meta property="article:tag" content="后端框架">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://www.yuan316.com/post/Django3.2%E6%A1%86%E6%9E%B6/assets/image-20210723182232002.png">
  
  
    <meta name="referrer" content="no-referrer-when-downgrade">
  
  
  <title>django起步 - My Blog</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/my-blog/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/my-blog/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/my-blog/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"walker_kwu.gitee.io","root":"/my-blog/","version":"1.9.2","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"left","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/my-blog/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/my-blog/js/utils.js" ></script>
  <script  src="/my-blog/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.2.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/my-blog/">
      <strong>木舟</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/my-blog/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="django起步"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        木舟
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-12-11 13:02" pubdate>
          2022年12月11日 下午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          10k 字
        
      </span>
    

    

    
    
      
        <span id="busuanzi_container_page_pv" style="display: none">
          <i class="iconfont icon-eye" aria-hidden="true"></i>
          <span id="busuanzi_value_page_pv"></span> 次
        </span>
        
      
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="padding-left: 2rem; margin-right: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">django起步</h1>
            
              <p class="note note-info">
                
                  
                    本文最后更新于：2023年5月23日 晚上
                  
                
              </p>
            
            
              <div class="markdown-body">
                
                <h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>在学习完前端相关知识(html/css/js/vue)后, 离我们向高级测试开发前进的道路中最后一个坎就只剩下 <strong>后端相关知识</strong>.</p>
<p>而后端相关知识中, 我们将会学习 <strong>django</strong>, 是属于 <strong>python</strong> 领域的框架.</p>
<p>python也是我们相对熟悉的语言了, 所以学习起来, 会更加轻松一些.</p>
<h1 id="什么是web后端"><a href="#什么是web后端" class="headerlink" title="什么是web后端"></a>什么是web后端</h1><p>web后端, 简单的理解: 提供/存储/修改数据的地方.</p>
<p>web后端, 实际上就是一个web应用程序:</p>
<blockquote>
<ol>
<li>接收并解析HTTP请求，获取具体的请求信息</li>
<li>处理本次HTTP请求，即完成本次请求的业务逻辑处理</li>
<li>构造并返回处理结果——HTTP响应</li>
</ol>
</blockquote>
<p><strong>什么是web后端框架</strong></p>
<p>所谓框架, 就是集成了一系列通用的功能, 使用框架, 能够快速构建出你想要的某种功能/项目.</p>
<p>所以后端框架, 就是集成了一系列用于搭建web后端的工具包.</p>
<p>比如:</p>
<ul>
<li>数据库连接</li>
<li>处理http请求</li>
<li>构建服务(ip + port)</li>
</ul>
<h1 id="Django介绍"><a href="#Django介绍" class="headerlink" title="Django介绍"></a>Django介绍</h1><p>Python下有许多款不同的 Web 框架, Django是重量级选手中最有代表性的一位。</p>
<p>Django 是一个开放源代码的 Web 应用框架，由 Python 写成。Django 遵守 BSD 版权，初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。</p>
<p>Django 采用了 MVT 的软件设计模式，即模型（Model），视图（View）和模板（Template）。</p>
<p>而MVT指的是：</p>
<blockquote>
<ol>
<li>M全拼为Model，与MVC中的M功能相同，负责和数据库交互，进行数据处理。</li>
<li>V全拼为View，与MVC中的C功能相同，接收请求，进行业务处理，返回应答。</li>
<li>T全拼为Template，与MVC中的V功能相同，负责封装构造要返回的html。</li>
</ol>
</blockquote>
<p>Django, 可以用一个词来概括它: 重型坦克</p>
<p>意思是它 <strong>全副武装</strong>, 你需要的, 不需要的它都具备.</p>
<p>所以, 使用django来搭建一个中大型项目, 是相当快的.</p>
<h1 id="Django安装"><a href="#Django安装" class="headerlink" title="Django安装"></a>Django安装</h1><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pip install django<br></code></pre></td></tr></table></figure>

<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs shell">pip源:<br>    https://pypi.douban.com/simple/  豆瓣源<br>    https://pypi.tuna.tsinghua.edu.cn/simple   清华源<br>        <br>使用格式:<br>    pip install django -i https://pypi.douban.com/simple/<br></code></pre></td></tr></table></figure>

<p>安装成功后, 打开 <strong>cmd</strong>, 选择一个项目运行如下命令:</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs shell">django-admin startproject demo<br><br>cd demo<br><br>python manage.py runserver<br></code></pre></td></tr></table></figure>

<p>demo就是我们创建的项目名称, 会在当前路径下生成一个 <strong>demo</strong> 文件夹</p>
<p>直接运行 <strong>runserver</strong> 会在 <strong>127.0.0.1</strong> 也就是本机地址,开辟一个端口,默认 <strong>8000</strong></p>
<p>我们也可以显式需要开辟的端口 <code>python manage.py runserver 8090</code></p>
<p><img src="http://www.yuan316.com/post/Django3.2%E6%A1%86%E6%9E%B6/assets/image-20210723182232002.png" srcset="/my-blog/img/loading.gif" lazyload alt="image-20210723182232002"></p>
<p>在浏览器中访问地址<code>http://127.0.0.1:8090</code>.看到一个小火箭的页面则表示正确安装了.</p>
<p><img src="http://www.yuan316.com/post/Django3.2%E6%A1%86%E6%9E%B6/assets/image-20210723181947547.png" srcset="/my-blog/img/loading.gif" lazyload alt="image-20210723181947547"></p>
<p><strong>当前目录结构</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">│─ manage.py    <span class="hljs-comment"># 终端脚本命令,提供了一系列用于生成文件或者目录的命令,也叫是django开发环境下的主要运行入口. 这个文件还有其他作用</span><br>└─ demo/        <span class="hljs-comment"># 主应用开发目录,保存了项目中的所有开发人员编写的代码, 目录是生成项目时指定的</span><br>    │- asgi.py      <span class="hljs-comment"># django3.0以后新增的，用于让django运行在异步编程模式的一个web应用对象</span><br>    │- settings.py  <span class="hljs-comment"># 默认开发配置文件</span><br>    │- urls.py      <span class="hljs-comment"># 路由列表目录, 一般用于设置接口地址, 也可以设置访问的页面(我们不学,我们有vue)</span><br>    │- wsgi.py      <span class="hljs-comment"># wsgi就是项目运行在wsgi服务器时的入口文件</span><br>    └- __init__.py<br></code></pre></td></tr></table></figure>

<h1 id="Django创建应用"><a href="#Django创建应用" class="headerlink" title="Django创建应用"></a>Django创建应用</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">python manage.py startapp app01<br></code></pre></td></tr></table></figure>

<p>app01是应用名称</p>
<p>这个应用, 你可以理解为功能模块.</p>
<p>比如:</p>
<ul>
<li>用例模块</li>
<li>缺陷模块</li>
<li>成员模块</li>
<li>首页模块</li>
</ul>
<p><strong>当前目录结构</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs python">│─ manage.py    <br>└─ demo/        <br>    │- asgi.py      <br>    │- settings.py  <br>    │- urls.py      <br>    │- wsgi.py      <br>    └- __init__.py<br>└─ app01         <span class="hljs-comment"># 子应用</span><br>    │- models    <span class="hljs-comment"># 该应用的模型类模块, 用来设置数据库表</span><br>    │- views     <span class="hljs-comment"># 该应用的视图模块, 用来编写业务逻辑函数</span><br>    │- tests     <span class="hljs-comment"># 该应用的单元测试模块</span><br>    │- apps      <span class="hljs-comment"># 该应用的一些配置，自动生成</span><br>    │- admin.py  <span class="hljs-comment"># 该应用的后台管理系统配置</span><br></code></pre></td></tr></table></figure>

<p>新建的应用, 需要进行 <strong>应用注册</strong></p>
<p>demo/settings.py中 <strong>INSTALLED_APPS</strong> 新增:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python">INSTALLED_APPS = [<br>    <span class="hljs-string">&#x27;django.contrib.admin&#x27;</span>,<br>    <span class="hljs-string">&#x27;django.contrib.auth&#x27;</span>,<br>    <span class="hljs-string">&#x27;django.contrib.contenttypes&#x27;</span>,<br>    <span class="hljs-string">&#x27;django.contrib.sessions&#x27;</span>,<br>    <span class="hljs-string">&#x27;django.contrib.messages&#x27;</span>,<br>    <span class="hljs-string">&#x27;django.contrib.staticfiles&#x27;</span>,<br>    <span class="hljs-string">&#x27;app01&#x27;</span> <span class="hljs-comment"># 新增</span><br>]<br></code></pre></td></tr></table></figure>

<p>因为我们搭建的测试平台, 用于公司内部 + 内网, 所以 <strong>csrf</strong> 安全校验我们并不需要</p>
<p>demo/settings.py中 <strong>MIDDLEWARE</strong> 注释掉: <code>django.middleware.csrf.CsrfViewMiddleware</code></p>
<h1 id="django接口路由配置"><a href="#django接口路由配置" class="headerlink" title="django接口路由配置"></a>django接口路由配置</h1><p>只要是通过后端服务开启的ip:port接收到http请求, 都会先在 <strong>demo/urls.py</strong> 中进行接口地址轮询</p>
<p>但是web项目中, 常常伴随很多的功能模块, 所以我们需要 <strong>分开管理</strong></p>
<p>demo/urls.py:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> admin<br><span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path, include<br><br>urlpatterns = [<br>    path(<span class="hljs-string">&#x27;admin/&#x27;</span>, admin.site.urls),<br>    path(<span class="hljs-string">&#x27;app01/&#x27;</span>, include(<span class="hljs-string">&#x27;app01.urls&#x27;</span>))  <span class="hljs-comment"># 如果http请求的接口地址为 ip:port/app01/xxx, 则会转发到 app01 应用中</span><br>]<br></code></pre></td></tr></table></figure>

<p>所以我们需要在 <strong>app01</strong> 中新建一个 <strong>urls.py</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path<br><br>urlpatterns = [<br>    <span class="hljs-comment"># ...</span><br>    <span class="hljs-comment"># 这里编写路由映射</span><br>]<br></code></pre></td></tr></table></figure>

<h1 id="快速新建一个接口"><a href="#快速新建一个接口" class="headerlink" title="快速新建一个接口"></a>快速新建一个接口</h1><p>app01/views.py中新建一个函数</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> JsonResponse<br><br><span class="hljs-comment"># Create your views here.</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">test</span>(<span class="hljs-params">request</span>):<br>    <span class="hljs-keyword">return</span> JsonResponse(&#123;<br>        <span class="hljs-string">&#x27;msg&#x27;</span>: <span class="hljs-string">&#x27;ok&#x27;</span><br>    &#125;)<br></code></pre></td></tr></table></figure>

<p>app01/urls.py中进行接口路由映射</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path<br><span class="hljs-keyword">from</span> .views <span class="hljs-keyword">import</span> test<br><br>urlpatterns = [<br>    path(<span class="hljs-string">&#x27;test&#x27;</span>, test)<br>]<br></code></pre></td></tr></table></figure>

<p>path 函数一般接收两个参数, 第一个参数为接口名称, 第二个参数为处理该接口逻辑的函数(注意,没有括号,就是写函数名).</p>
<p>我们可以通过 postman 或者是其他的接口调试工具, 来进行测试</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">url = <span class="hljs-string">&quot;http://127.0.0.1:8090/app01/test&quot;</span><br></code></pre></td></tr></table></figure>

<p>因为我们没有限制请求方式, 也没有接收请求体, 所以直接请求就好了, post/get都可以.</p>
<p>不出意外, 你可以获取到返回的数据:</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;msg&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;ok&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure>

<h1 id="django请求解析"><a href="#django请求解析" class="headerlink" title="django请求解析"></a>django请求解析</h1><p>每个接口处理函数, 都会接收一个回调参数 <strong>request</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> JsonResponse<br><span class="hljs-keyword">import</span> json<br><span class="hljs-comment"># Create your views here.</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">test</span>(<span class="hljs-params">request</span>):<br>    <span class="hljs-built_in">print</span>(request.method) <span class="hljs-comment"># 获取请求方式, 输出的都是大写 如 POST</span><br>    <span class="hljs-built_in">print</span>(request.META) <span class="hljs-comment"># 获取所有请求头</span><br>    <span class="hljs-built_in">print</span>(request.META.get(<span class="hljs-string">&#x27;CONTENT_TYPE&#x27;</span>)) <span class="hljs-comment"># 获取请求头</span><br>    <span class="hljs-comment"># 获取请求头, 自定义的请求头, 必须要按照如 test-header 的格式 自定义请求头django都会自动转化为大写,并且加上前缀 HTTP_</span><br>    <span class="hljs-built_in">print</span>(request.META.get(<span class="hljs-string">&#x27;HTTP_TEST_HEADER&#x27;</span>))<br>    <span class="hljs-built_in">print</span>(request.COOKIES) <span class="hljs-comment"># 获取所有的 cookies, 键和值都是字符串</span><br>    <span class="hljs-built_in">print</span>(request.session) <span class="hljs-comment"># 获取会话数据</span><br>    <span class="hljs-built_in">print</span>(request.GET.get(<span class="hljs-string">&#x27;age&#x27;</span>)) <span class="hljs-comment"># 获取请求参数</span><br>    <span class="hljs-built_in">print</span>(request.POST.get(<span class="hljs-string">&#x27;age&#x27;</span>)) <span class="hljs-comment"># 获取form-data, 也就是表单数据</span><br>    <span class="hljs-built_in">print</span>(request.FILES.get(<span class="hljs-string">&#x27;file1&#x27;</span>)) <span class="hljs-comment"># 获取上传的文件, 传输方式为form-data</span><br>    <span class="hljs-built_in">print</span>(json.loads(request.body)) <span class="hljs-comment"># 获取json请求体数据, 比如为POST请求时, 且 请求头中的 content-type 为 application/json</span><br>    <span class="hljs-keyword">return</span> JsonResponse(&#123;<br>        <span class="hljs-string">&#x27;msg&#x27;</span>: <span class="hljs-string">&#x27;ok&#x27;</span><br>    &#125;)<br></code></pre></td></tr></table></figure>

<h1 id="Django-ORM"><a href="#Django-ORM" class="headerlink" title="Django ORM"></a>Django ORM</h1><p>Django中内嵌了ORM框架，不需要直接编写SQL语句进行数据库操作，而是通过定义模型类，操作模型类来完成对数据库中表的增删改查和创建等操作。</p>
<blockquote>
<p>O是object，也就<strong>类对象</strong>的意思。</p>
<p>R是relation，翻译成中文是关系，也就是<strong>关系数据库</strong>的意思。</p>
<p>M是mapping，是<strong>映射</strong>的意思。</p>
</blockquote>
<p>映射：</p>
<blockquote>
<p>类：sql语句table表</p>
<p>类成员变量：table表中的字段、类型和约束</p>
<p>类对象：sql表的表记录</p>
</blockquote>
<p>ORM的优点</p>
<blockquote>
<ul>
<li>数据模型类都在一个地方定义，更容易更新和维护，也利于重用代码。</li>
<li>ORM 有现成的工具，很多功能都可以自动完成，比如数据消除、预处理、事务等等。</li>
<li>它迫使你使用 MVC 架构，ORM 就是天然的 Model，最终使代码更清晰。</li>
<li>基于 ORM 的业务代码比较简单，代码量少，语义性好，容易理解。</li>
<li>新手对于复杂业务容易写出性能不佳的 SQL,有了ORM不必编写复杂的SQL语句, 只需要通过操作模型对象即可同步修改数据表中的数据.</li>
<li>开发中应用ORM将来如果要切换数据库.只需要切换ORM底层对接数据库的驱动【修改配置文件的连接地址即可】</li>
</ul>
</blockquote>
<p>ORM 也有缺点</p>
<blockquote>
<ul>
<li>ORM 库不是轻量级工具，需要花很多精力学习和设置，甚至不同的框架，会存在不同操作的ORM。</li>
<li>对于复杂的业务查询，ORM表达起来比原生的SQL要更加困难和复杂。</li>
<li>ORM操作数据库的性能要比使用原生的SQL差。</li>
<li>ORM 抽象掉了数据库层，开发者无法了解底层的数据库操作，也无法定制一些特殊的 SQL。【自己使用pymysql另外操作即可，用了ORM并不表示当前项目不能使用别的数据库操作工具了。】</li>
</ul>
</blockquote>
<p>我们可以通过以下步骤来使用django的数据库操作</p>
<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs markdown"><span class="hljs-bullet">1.</span> 配置数据库连接信息<br><span class="hljs-bullet">2.</span> 在models.py中定义模型类<br><span class="hljs-bullet">3.</span> 生成数据库迁移文件并执行迁文件<br><span class="hljs-bullet">4.</span> 通过模型类对象提供的方法或属性完成数据表的增删改查操作<br></code></pre></td></tr></table></figure>

<h2 id="配置数据库连接"><a href="#配置数据库连接" class="headerlink" title="配置数据库连接"></a>配置数据库连接</h2><p>在settings.py中保存了数据库的连接配置信息，Django默认初始配置使用<strong>sqlite</strong>数据库。</p>
<ol>
<li>使用<strong>MySQL</strong>数据库首先需要安装驱动程序</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pip install PyMySQL<br></code></pre></td></tr></table></figure>

<ol>
<li>在Django的工程同名子目录的<code>demo/__init__.py</code>文件中添加如下语句</li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> pymysql <span class="hljs-keyword">import</span> install_as_MySQLdb<br>install_as_MySQLdb() <span class="hljs-comment"># 让pymysql以MySQLDB的运行模式和Django的ORM对接运行</span><br></code></pre></td></tr></table></figure>

<p>作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。</p>
<ol start="2">
<li>修改demo/settings.py <strong>DATABASES</strong> 配置信息</li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs python">DATABASES = &#123;<br>    <span class="hljs-string">&#x27;default&#x27;</span>: &#123;<br>        <span class="hljs-string">&#x27;ENGINE&#x27;</span>: <span class="hljs-string">&#x27;django.db.backends.mysql&#x27;</span>,<br>        <span class="hljs-string">&#x27;HOST&#x27;</span>: <span class="hljs-string">&#x27;127.0.0.1&#x27;</span>,  <span class="hljs-comment"># 数据库主机</span><br>        <span class="hljs-string">&#x27;PORT&#x27;</span>: <span class="hljs-number">3306</span>,  <span class="hljs-comment"># 数据库端口</span><br>        <span class="hljs-string">&#x27;USER&#x27;</span>: <span class="hljs-string">&#x27;root&#x27;</span>,  <span class="hljs-comment"># 数据库用户名</span><br>        <span class="hljs-string">&#x27;PASSWORD&#x27;</span>: <span class="hljs-string">&#x27;123&#x27;</span>,  <span class="hljs-comment"># 数据库用户密码</span><br>        <span class="hljs-string">&#x27;NAME&#x27;</span>: <span class="hljs-string">&#x27;student&#x27;</span>  <span class="hljs-comment"># 数据库名字</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="定义模型类"><a href="#定义模型类" class="headerlink" title="定义模型类"></a>定义模型类</h2><blockquote>
<ul>
<li>模型类被定义在”子应用/models.py”文件中。</li>
<li>模型类必须直接或者间接继承自django.db.models.Model类。</li>
</ul>
</blockquote>
<p>接下来以学生管理为例进行演示。[系统大概3-4表，学生信息，课程信息，老师信息]，创建子应用student，注册子应用并引入子应用路由.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">python manage.py startapp student<br></code></pre></td></tr></table></figure>

<p>demo/settings.py进行应用注册</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">INSTALLED_APPS = [<br>    <span class="hljs-comment"># ...</span><br>    <span class="hljs-string">&#x27;student&#x27;</span>,<br>]<br></code></pre></td></tr></table></figure>

<p>在student应用文件夹中新建 urls.py<br>然后修改demo/urls.py</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">urlpatterns = [<br>    <span class="hljs-comment"># 省略，如果前面有重复的路由，改动以下。</span><br>    path(<span class="hljs-string">&quot;student/&quot;</span>, include(<span class="hljs-string">&quot;student.urls&quot;</span>)),<br>]<br></code></pre></td></tr></table></figure>


<p>student/models.py</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db <span class="hljs-keyword">import</span> models<br><br><span class="hljs-comment"># Create your models here.</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span>(models.Model):<br><br>    wid = models.AutoField(primary_key=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># 设置自增id主键</span><br>    name = models.CharField(max_length=<span class="hljs-number">20</span>, db_index=<span class="hljs-literal">True</span>)<br>    age = models.IntegerField()<br>    classFrom = models.CharField(max_length=<span class="hljs-number">5</span>, db_index=<span class="hljs-literal">True</span>)<br><br>    <span class="hljs-keyword">class</span> <span class="hljs-title class_">Meta</span>:<br>        db_table = <span class="hljs-string">&#x27;tb_student&#x27;</span>  <span class="hljs-comment"># 指明数据库表名,如果没有指定表明,则默认为子应用目录名_模型名称,例如: student_student</span><br></code></pre></td></tr></table></figure>

<p><strong>数据库表名</strong></p>
<p>模型类如果未指明表名db_table，Django默认以 <strong>小写app应用名_小写模型类名</strong> 为数据库表名。</p>
<p>可通过<strong>db_table</strong> 指明数据库表名。</p>
<p><strong>关于主键</strong></p>
<p>django会为表创建自动增长的主键列，每个模型只能有一个主键列。</p>
<p>默认创建的主键列属性为id，可以使用pk代替，pk全拼为primary key。</p>
<p>如果使用选项设置某个字段的约束属性为主键列(primary_key)后，django不会再创建自动增长的主键列。</p>
<h3 id="常用的模型字段类型"><a href="#常用的模型字段类型" class="headerlink" title="常用的模型字段类型"></a>常用的模型字段类型</h3><p>字段类型</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>AutoField</td>
<td>自动增长的IntegerField，通常不用指定，不指定时Django会自动创建属性名为id的自动增长属性</td>
</tr>
<tr>
<td>BooleanField</td>
<td>布尔字段，值为True或False</td>
</tr>
<tr>
<td>CharField</td>
<td>字符串，参数max_length表示最大字符个数，对应mysql中的varchar</td>
</tr>
<tr>
<td>TextField</td>
<td>大文本字段，一般大段文本（超过4000个字符）才使用。</td>
</tr>
<tr>
<td>IntegerField</td>
<td>整数</td>
</tr>
<tr>
<td>FloatField</td>
<td>浮点数</td>
</tr>
<tr>
<td>DateField</td>
<td>日期参数auto_now表示每次保存对象时，自动设置该字段为当前时间。参数auto_now_add表示当对象第一次被创建时自动设置当前。参数auto_now_add和auto_now是相互排斥的，一起使用会发生错误。</td>
</tr>
<tr>
<td>TimeField</td>
<td>时间，参数同DateField</td>
</tr>
<tr>
<td>DateTimeField</td>
<td>日期时间，参数同DateField</td>
</tr>
</tbody></table>
<h3 id="常用字段约束"><a href="#常用字段约束" class="headerlink" title="常用字段约束"></a>常用字段约束</h3><p>约束选项</p>
<table>
<thead>
<tr>
<th>选项</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>null</td>
<td>如果为True，表示允许为空，默认值是False。相当于python的None</td>
</tr>
<tr>
<td>db_column</td>
<td>字段的名称，如果未指定，则使用属性的名称。</td>
</tr>
<tr>
<td>db_index</td>
<td>若值为True, 则在表中会为此字段创建索引，默认值是False。 相当于SQL语句中的key</td>
</tr>
<tr>
<td>default</td>
<td>默认值，当不填写数据时，使用该选项的值作为数据的默认值。</td>
</tr>
<tr>
<td>primary_key</td>
<td>如果为True，则该字段会成为模型的主键，默认值是False，一般不用设置，系统默认设置。</td>
</tr>
<tr>
<td>unique</td>
<td>如果为True，则该字段在表中必须有唯一值，默认值是False。相当于SQL语句中的unique</td>
</tr>
<tr>
<td>max_length</td>
<td>CharField限制的最大长度</td>
</tr>
</tbody></table>
<h3 id="外键"><a href="#外键" class="headerlink" title="外键"></a>外键</h3><p>比如 一个学生 归属于 哪个班级</p>
<p>那么学生表中, 就需要创建一个外键关联 班级表</p>
<p>所以我们可以改写 student/models.py</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db <span class="hljs-keyword">import</span> models<br><br><span class="hljs-comment"># Create your models here.</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Classes</span>(models.Model):<br><br>    wid = models.AutoField(primary_key=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># 设置自增id主键</span><br>    className = models.CharField(max_length=<span class="hljs-number">10</span>)<br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span>(models.Model):<br><br>    wid = models.AutoField(primary_key=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># 设置自增id主键</span><br>    name = models.CharField(max_length=<span class="hljs-number">20</span>, db_index=<span class="hljs-literal">True</span>)<br>    age = models.IntegerField()<br>    <span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">        models.ForeignKey(&#x27;app.modelName&#x27;) 如果外键关联的是其他应用的模型</span><br><span class="hljs-string">        也可以导入</span><br><span class="hljs-string">        from app import modelName</span><br><span class="hljs-string">        models.ForeignKey(modelName)</span><br><span class="hljs-string">    &quot;&quot;&quot;</span><br>    classFrom = models.ForeignKey(Classes, on_delete=models.CASCADE)<br><br>    <span class="hljs-keyword">class</span> <span class="hljs-title class_">Meta</span>:<br>        db_table = <span class="hljs-string">&#x27;tb_student&#x27;</span>  <span class="hljs-comment"># 指明数据库表名,如果没有指定表明,则默认为子应用目录名_模型名称,例如: student_student</span><br></code></pre></td></tr></table></figure>

<p>这个时候, 创建的 student 表中, 会自动创建一个外键字段 <strong>classFrom_id</strong>, 存入的就是 classes 表中的 wid 字段值</p>
<p><strong>外键特殊约束</strong></p>
<p>在设置外键时，需要通过<strong>on_delete</strong>选项指明主表删除数据时，对于外键引用表数据如何处理.</p>
<p>上述例子中, 代表着, 关联的班级如果被删除了, 那么关联的学生记录也会被删除.</p>
<p>在django.db.models中包含了可选常量：</p>
<ul>
<li><strong>CASCADE</strong> 级联，删除主表数据时连通一起删除外键表中数据</li>
<li><strong>PROTECT</strong> 保护，通过抛出<strong>ProtectedError</strong>异常，来阻止删除主表中被外键应用的数据</li>
<li><strong>SET_NULL</strong> 设置为NULL，仅在该字段null=True允许为null时可用</li>
<li><strong>SET_DEFAULT</strong> 设置为默认值，仅在该字段设置了默认值时可用</li>
<li><strong>DO_NOTHING</strong> 什么都不做，一切都看数据库级别的约束，注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似</li>
<li><strong>SET()</strong> 设置为特定值或者调用特定方法，例如：</li>
</ul>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db <span class="hljs-keyword">import</span> models<br><br><span class="hljs-comment"># Create your models here.</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Classes</span>(models.Model):<br><br>    wid = models.AutoField(primary_key=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># 设置自增id主键</span><br>    className = models.CharField(max_length=<span class="hljs-number">10</span>)<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">setDefaultClass</span>():<br>    <span class="hljs-keyword">return</span> Classes.objects.first()  <span class="hljs-comment"># 返回第一条数据</span><br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span>(models.Model):<br><br>    wid = models.AutoField(primary_key=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># 设置自增id主键</span><br>    name = models.CharField(max_length=<span class="hljs-number">20</span>, db_index=<span class="hljs-literal">True</span>)<br>    age = models.IntegerField()<br>    <span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">        models.ForeignKey(&#x27;app.modelName&#x27;) 如果外键关联的是其他应用的模型</span><br><span class="hljs-string">        也可以导入</span><br><span class="hljs-string">        from app import modelName</span><br><span class="hljs-string">        models.ForeignKey(modelName)</span><br><span class="hljs-string">    &quot;&quot;&quot;</span><br>    classFrom = models.ForeignKey(Classes, on_delete=models.SET(setDefaultClass)) <span class="hljs-comment"># 被删除后, 默认给class表中第一条数据</span><br><br>    <span class="hljs-keyword">class</span> <span class="hljs-title class_">Meta</span>:<br>        db_table = <span class="hljs-string">&#x27;tb_student&#x27;</span>  <span class="hljs-comment"># 指明数据库表名,如果没有指定表明,则默认为子应用目录名_模型名称,例如: student_student</span><br></code></pre></td></tr></table></figure>

<h2 id="数据迁移"><a href="#数据迁移" class="headerlink" title="数据迁移"></a>数据迁移</h2><p>将模型类定义表架构的代码转换成SQL同步到数据库中，这个过程就是数据迁移。</p>
<p>django中的数据迁移，就是一个类，这个类提供了一系列的终端命令，帮我们完成数据迁移的工作。</p>
<p>只要是修改任何一个models.py 文件, 都需要进行数据迁移</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">python manage.py makemigrations <span class="hljs-comment"># 可以指定迁移的应用, python manage.py makemigrations appName</span><br>python manage.py migrate<br></code></pre></td></tr></table></figure>

<h2 id="ORM数据操作"><a href="#ORM数据操作" class="headerlink" title="ORM数据操作"></a>ORM数据操作</h2><h3 id="添加记录"><a href="#添加记录" class="headerlink" title="添加记录"></a>添加记录</h3><p><strong>save方法</strong></p>
<p>通过创建模型类对象，执行对象的save()方法保存到数据库中。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student(<br>    name=<span class="hljs-string">&quot;刘德华&quot;</span>,<br>    age=<span class="hljs-number">17</span>,<br>    sex=<span class="hljs-literal">True</span><br>)<br>student.save()<br><span class="hljs-built_in">print</span>(student.wid) <span class="hljs-comment"># 判断是否新增有ID</span><br></code></pre></td></tr></table></figure>

<p><strong>create方法</strong></p>
<p>通过模型类.objects.create()保存，返回生成的模型类对象。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.create(<br>    name=<span class="hljs-string">&quot;赵本山&quot;</span>,<br>    age=<span class="hljs-number">50</span>,<br>    sex=<span class="hljs-literal">True</span><br>)<br><span class="hljs-built_in">print</span>(student.wid)<br></code></pre></td></tr></table></figure>

<h3 id="查询记录"><a href="#查询记录" class="headerlink" title="查询记录"></a>查询记录</h3><p>ORM中针对查询结果的限制,提供了一个查询集[QuerySet]或单个QuerySet</p>
<p>一个查询集, 可以看成一个数组,可以进行for循环取值,也可以通过索引取值</p>
<p><strong>all</strong></p>
<p>查询所有对象，返回queryset对象。查询集，也称查询结果集、QuerySet，表示从数据库中获取的对象集合。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">students = Student.objects.<span class="hljs-built_in">all</span>()  <span class="hljs-comment"># select * from student;</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;students:&quot;</span>,students)<br></code></pre></td></tr></table></figure>

<p><strong>filter</strong></p>
<p>筛选条件相匹配的对象，返回queryset查询集。没有数据,则返回一个空查询集</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 查询所有的女生</span><br>students = Student.objects.<span class="hljs-built_in">filter</span>(sex=<span class="hljs-number">0</span>) <span class="hljs-comment"># select * from student where sex = 0;</span><br><span class="hljs-built_in">print</span>(students)<br></code></pre></td></tr></table></figure>

<p><strong>get</strong></p>
<p>返回与所给筛选条件相匹配的对象，返回结果有且只有一个，如果查询的结果,一个记录都没有,会报错.</p>
<p>所以我们一般对不确定的查询,都会使用<strong>filter</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.get(wid=<span class="hljs-number">1</span>)  <span class="hljs-comment"># select * from where wid = 1;</span><br><span class="hljs-built_in">print</span>(student)<br></code></pre></td></tr></table></figure>

<h3 id="修改记录"><a href="#修改记录" class="headerlink" title="修改记录"></a>修改记录</h3><p><strong>save</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.get(wid=<span class="hljs-number">1</span>)<br><span class="hljs-built_in">print</span>(student)<br>student.age = <span class="hljs-number">19</span><br>student.save()<br></code></pre></td></tr></table></figure>

<p><strong>update</strong></p>
<p>多数据更新</p>
<p><strong>使用模型类.objects.filter().update()</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># update是全局更新，只要符合更新的条件，则全部更新，因此强烈建议加上条件！！！</span><br>student = Student.objects.<span class="hljs-built_in">filter</span>(name=<span class="hljs-string">&quot;赵华&quot;</span>,age=<span class="hljs-number">22</span>).update(name=<span class="hljs-string">&quot;刘芙蓉&quot;</span>,sex=<span class="hljs-number">1</span>)<br><span class="hljs-built_in">print</span>(student)<br></code></pre></td></tr></table></figure>

<h3 id="删除记录"><a href="#删除记录" class="headerlink" title="删除记录"></a>删除记录</h3><p><strong>模型类对象.delete</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.get(wid=<span class="hljs-number">13</span>)<br>student.delete()<br></code></pre></td></tr></table></figure>

<p><strong>filter + delete 批量删除</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">Student.objects.<span class="hljs-built_in">filter</span>(<span class="hljs-built_in">id</span>=<span class="hljs-number">14</span>).delete() <br></code></pre></td></tr></table></figure>

<h3 id="关联查询"><a href="#关联查询" class="headerlink" title="关联查询"></a>关联查询</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.get(wid=<span class="hljs-number">13</span>)<br><span class="hljs-built_in">print</span>(student.classFrom.className)<br></code></pre></td></tr></table></figure>
                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/my-blog/categories/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/" class="category-chain-item">测试开发</a>
  
  
    <span>></span>
    
  <a href="/my-blog/categories/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/Django/" class="category-chain-item">Django</a>
  
  

  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/my-blog/tags/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/">#测试开发</a>
      
        <a href="/my-blog/tags/%E6%B5%8B%E8%AF%95%E5%B9%B3%E5%8F%B0/">#测试平台</a>
      
        <a href="/my-blog/tags/%E5%90%8E%E7%AB%AF%E6%A1%86%E6%9E%B6/">#后端框架</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>django起步</div>
      <div>https://walker_kwu.gitee.io/my-blog/2022/12/11/notes/django/strat/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>木舟</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年12月11日</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>更新于</div>
          <div>2023年5月23日</div>
        </div>
      
      <div class="license-meta-item">
        <div>许可协议</div>
        <div>
          
            
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="BY - 署名">
                <i class="iconfont icon-by"></i>
              </span>
              </a>
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="NC - 非商业性使用">
                <i class="iconfont icon-nc"></i>
              </span>
              </a>
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="SA - 相同方式共享">
                <i class="iconfont icon-sa"></i>
              </span>
              </a>
            
          
        </div>
      </div>
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/my-blog/2022/12/12/notes/django/ormAction/" title="Django-ORM操作进阶">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Django-ORM操作进阶</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/my-blog/2022/12/06/notes/vue/vite/" title="Vite--新一代前端构建工具">
                        <span class="hidden-mobile">Vite--新一代前端构建工具</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <span>By 木舟</span> <i class="iconfont icon-love"></i> 
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="busuanzi_container_site_pv" style="display: none">
        总访问量 
        <span id="busuanzi_value_site_pv"></span>
         次
      </span>
    
    
      <span id="busuanzi_container_site_uv" style="display: none">
        总访客数 
        <span id="busuanzi_value_site_uv"></span>
         人
      </span>
    
    
  
</div>

  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/my-blog/js/events.js" ></script>
<script  src="/my-blog/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/my-blog/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      collapseDepth   : CONFIG.toc.collapseDepth || 0,
      scrollSmooth    : true,
      headingsOffset  : -boardTop
    });
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/my-blog/js/local-search.js" ></script>

  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/my-blog/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
